package com.word.vacation.sdk.bridge;

import android.app.Activity;
import android.os.Handler;
import android.os.Looper;

import com.word.vacation.sdk.WordBusiness;

import java.lang.ref.WeakReference;
import java.lang.reflect.Method;

public class WordCocosBridge implements WordCocosIAP {

    private static WordCocosBridge callbackApi;
    public static WeakReference<Activity> mainGameActivity;
    private Method evalString;
    private Method runOnGLThread;
    private static Handler handler = new Handler(Looper.getMainLooper());

    public static WordCocosBridge getInstance() {
        if (callbackApi == null) {
            callbackApi = new WordCocosBridge();
        }
        return callbackApi;
    }

    public void setMainGameActivity(Activity activity) {
        mainGameActivity = new WeakReference<>(activity);
    }

    @Override
    public void XSSdkCallback(String action, String jsonData) {
        init();
        if (mainGameActivity != null && mainGameActivity.get() != null) {
            handler.post(createGlThreadRunnable(action,jsonData));
        }
    }

    private void init() {
        initEvalString();
        initRunOnGLThread();
    }

    private void initRunOnGLThread() {
        if (runOnGLThread == null) {
            realInitRunOnGLThread();
        }
    }

    private void realInitRunOnGLThread() {
        try {
            runOnGLThread = Class.forName("org.cocos2dx.lib.Cocos2dxActivity", false, WordBusiness.context.getClassLoader()).getDeclaredMethod("runOnGLThread", Runnable.class);
            runOnGLThread.setAccessible(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initEvalString() {
        if (evalString == null) {
            realInitEvalString();
        }
    }

    private void realInitEvalString() {
        try {
            evalString = Class.forName("org.cocos2dx.lib.Cocos2dxJavascriptJavaBridge", false, WordBusiness.context.getClassLoader()).getDeclaredMethod("evalString", String.class);
            evalString.setAccessible(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Runnable  createGlThreadRunnable (String action, String jsonData){
        return () -> {
            invok(action,jsonData);
        };
    }

    private void invok(String action, String jsonData) {
        try {
            runOnGLThread.invoke(mainGameActivity.get(), (Runnable) () -> {
                realInvoke(action,jsonData);
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void realInvoke(String action, String jsonData) {
        try {
            evalString.invoke(null, String.format("window.WVaSdkCallback('%s','%s')", action, jsonData));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
